/*
 * Licensed to the 南京汇海交通科技有限公司
 *
 * Copyright (c) 2025.
 * All rights reserved.
 *
 * 本软件属南京汇海交通科技有限公司所有，在未获得南京汇海交通科技有限公司正式授权情况下，任何企业和个人，不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。
 */
package com.chframework.common.thread.wrapper;

import org.springframework.lang.NonNull;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * Bingo，
 * BenchmarksFuture<T> 是 CompletableFuture<T> 的代理类，默认采用系统自定义的JDK线程池
 *
 * CompletableFuture使用
 * https://www.zhihu.com/question/37133275/answer/3064272084
 *
 * 异步编程利器：CompletableFuture详解
 * https://www.cnblogs.com/ludongguoa/p/15316488.html
 *
 * @param <T> 异步响应结果的引用类型
 */
public final class BenchmarksFuture<T> extends CompletableFutureAgent<T> {

    private static ExecutorService threadPool;

    /**
     * 设置异步任务编排的线程池
     */
    public static void setThreadPool(@NonNull ExecutorService threadPool) {
        setThreadPool(threadPool, false);
    }

    /**
     * 设置异步任务编排的线程池
     */
    public static void setThreadPool(@NonNull ExecutorService threadPool, boolean overwrite) {
        if (overwrite) {
            BenchmarksFuture.threadPool = threadPool;
        } else if (BenchmarksFuture.threadPool == null) {
            BenchmarksFuture.threadPool = threadPool;
        }
    }

    BenchmarksFuture(@NonNull CompletableFuture<T> completableFuture) {
        super(completableFuture);
    }

    //region 静态方法包装

    /**
     * 合并多个complete为一个，等待全部完成。
     * <p>
     * 当所有的传入的CompletableFuture实例都完成的时候，会返回一个新建的CompletableFuture。
     * 也就是程序将会阻塞在此方法调用，直到所有传入CompletableFuture都完成，这个时候返回值CompletableFuture实例也完成。
     */
    public static BenchmarksFuture<Void> allOf(CompletableFuture<?>... cfs) {
        return new BenchmarksFuture<>(CompletableFuture.allOf(cfs));
    }

    /**
     * 合并多个complete为一个，等待其中之一完成。
     * <p>
     * 当所有的传入的CompletableFuture实例中只要有一个实例完成的时候，会返回一个新建的CompletableFuture。
     * 也就是程序将会阻塞在此方法调用，直到有一个传入的CompletableFuture完成，这个时候返回值CompletableFuture实例也完成。
     */
    public static BenchmarksFuture<Object> anyOf(CompletableFuture<?>... cfs) {
        return new BenchmarksFuture<>(CompletableFuture.anyOf(cfs));
    }

    /**
     * completedFuture 用于构建一个现成的CompletableFuture对象
     */
    public static <U> BenchmarksFuture<U> completedFuture(U value) {
        return new BenchmarksFuture<>(CompletableFuture.completedFuture(value));
    }

    /**
     * 用于构建一个没有入参也没有出参的任务
     */
    public static BenchmarksFuture<Void> runAsync(Runnable runnable) {
        return new BenchmarksFuture<>(CompletableFuture.runAsync(runnable, BenchmarksFuture.threadPool));
    }

    /**
     * 用于构建一个没有入参但是有出参的任务
     */
    public static <U> BenchmarksFuture<U> supplyAsync(Supplier<U> supplier) {
        return new BenchmarksFuture<>(CompletableFuture.supplyAsync(supplier, BenchmarksFuture.threadPool));
    }

    //endregion

    //region 异步方法包装-使用自定义线程池

    /**
     * 能接受上一步结果，有返回值
     * <p>
     * 表示某个任务执行完成后执行的动作，即回调方法，会将该任务的执行结果即方法返回值作为入参传递到回调方法中
     */
    @Override
    public <U> BenchmarksFuture<U> thenApplyAsync(Function<? super T, ? extends U> fn) {
        return new BenchmarksFuture<>(super.completableFuture.thenApplyAsync(fn, BenchmarksFuture.threadPool));
    }

    /**
     * 能接受上一步结果，但是无返回值
     */
    @Override
    public BenchmarksFuture<Void> thenAcceptAsync(Consumer<? super T> action) {
        return new BenchmarksFuture<>(super.completableFuture.thenAcceptAsync(action, BenchmarksFuture.threadPool));
    }

    /**
     * 不能获取上一步的执行结果
     */
    @Override
    public BenchmarksFuture<Void> thenRunAsync(Runnable action) {
        return new BenchmarksFuture<>(super.completableFuture.thenRunAsync(action, BenchmarksFuture.threadPool));
    }

    /**
     * 在某个任务执行完成后，将该任务的执行结果作为入参，执行指定的方法。
     * 该方法会返回一个新的 CompletableFuture 实例。
     */
    @Override
    public <U> BenchmarksFuture<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn) {
        return new BenchmarksFuture<>(super.completableFuture.thenComposeAsync(fn, BenchmarksFuture.threadPool));
    }

    /**
     * 组合处理，只有两个都正常执行完了才会执行某个任务
     */
    @Override
    public <U, V> BenchmarksFuture<V> thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T, ? super U, ? extends V> fn) {
        return new BenchmarksFuture<>(super.completableFuture.thenCombineAsync(other, fn, BenchmarksFuture.threadPool));
    }

    /**
     * 组合处理，只有两个都正常执行完了才会执行某个任务
     */
    @Override
    public <U> BenchmarksFuture<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action) {
        return new BenchmarksFuture<>(super.completableFuture.thenAcceptBothAsync(other, action, BenchmarksFuture.threadPool));
    }

    /**
     * 组合处理，只有两个都正常执行完了才会执行某个任务
     */
    @Override
    public BenchmarksFuture<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action) {
        return new BenchmarksFuture<>(super.completableFuture.runAfterBothAsync(other, action, BenchmarksFuture.threadPool));
    }

    /**
     * 组合处理，只要其中一个执行完了就会执行某个任务
     */
    @Override
    public <U> BenchmarksFuture<U> applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T, U> fn) {
        return new BenchmarksFuture<>(super.completableFuture.applyToEitherAsync(other, fn, BenchmarksFuture.threadPool));
    }

    /**
     * 组合处理，只要其中一个执行完了就会执行某个任务
     */
    @Override
    public BenchmarksFuture<Void> acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action) {
        return new BenchmarksFuture<>(super.completableFuture.acceptEitherAsync(other, action, BenchmarksFuture.threadPool));
    }

    /**
     * 组合处理，只要其中一个执行完了就会执行某个任务
     */
    @Override
    public BenchmarksFuture<Void> runAfterEitherAsync(CompletionStage<?> other, Runnable action) {
        return new BenchmarksFuture<>(super.completableFuture.runAfterEitherAsync(other, action, BenchmarksFuture.threadPool));
    }

    /**
     * 当某个任务执行完成后执行的回调方法，会将执行结果或者执行期间抛出的异常传递给回调方法。
     * 如果是正常执行则异常为null，回调方法对应的CompletableFuture的result和该任务一致；
     * 如果该任务正常执行，则get方法返回执行结果；
     * 如果是执行异常，则get方法抛出异常。
     */
    @Override
    public BenchmarksFuture<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action) {
        return new BenchmarksFuture<>(super.completableFuture.whenCompleteAsync(action, BenchmarksFuture.threadPool));
    }

    /**
     * 与whenCompleteAsync类似，不同的是，如果任务执行异常允许返回一个默认值。
     */
    @Override
    public <U> BenchmarksFuture<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn) {
        return new BenchmarksFuture<>(super.completableFuture.handleAsync(fn, BenchmarksFuture.threadPool));
    }

    //endregion

    //region 成员方法包装

    /**
     * 能接受上一步结果，有返回值
     * <p>
     * 表示某个任务执行完成后执行的动作，即回调方法，会将该任务的执行结果即方法返回值作为入参传递到回调方法中
     */
    @Override
    public <U> BenchmarksFuture<U> thenApply(Function<? super T, ? extends U> fn) {
        return new BenchmarksFuture<>(super.completableFuture.thenApply(fn));
    }

    /**
     * 能接受上一步结果，但是无返回值
     */
    @Override
    public BenchmarksFuture<Void> thenAccept(Consumer<? super T> action) {
        return new BenchmarksFuture<>(super.completableFuture.thenAccept(action));
    }

    /**
     * 不能获取上一步的执行结果
     */
    @Override
    public BenchmarksFuture<Void> thenRun(Runnable action) {
        return new BenchmarksFuture<>(super.completableFuture.thenRun(action));
    }

    /**
     * 在某个任务执行完成后，将该任务的执行结果作为入参，执行指定的方法。
     * 该方法会返回一个新的 CompletableFuture 实例。
     */
    @Override
    public <U> BenchmarksFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn) {
        return new BenchmarksFuture<>(super.completableFuture.thenCompose(fn));
    }

    /**
     * 组合处理，只有两个都正常执行完了才会执行某个任务
     */
    @Override
    public <U, V> BenchmarksFuture<V> thenCombine(CompletionStage<? extends U> other, BiFunction<? super T, ? super U, ? extends V> fn) {
        return new BenchmarksFuture<>(super.completableFuture.thenCombine(other, fn));
    }

    /**
     * 组合处理，只有两个都正常执行完了才会执行某个任务
     */
    @Override
    public <U> BenchmarksFuture<Void> thenAcceptBoth(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action) {
        return new BenchmarksFuture<>(super.completableFuture.thenAcceptBoth(other, action));
    }

    /**
     * 组合处理，只有两个都正常执行完了才会执行某个任务
     */
    @Override
    public BenchmarksFuture<Void> runAfterBoth(CompletionStage<?> other, Runnable action) {
        return new BenchmarksFuture<>(super.completableFuture.runAfterBoth(other, action));
    }

    /**
     * 组合处理，只要其中一个执行完了就会执行某个任务
     */
    @Override
    public <U> BenchmarksFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn) {
        return new BenchmarksFuture<>(super.completableFuture.applyToEither(other, fn));
    }

    /**
     * 组合处理，只要其中一个执行完了就会执行某个任务
     */
    @Override
    public BenchmarksFuture<Void> acceptEither(CompletionStage<? extends T> other, Consumer<? super T> action) {
        return new BenchmarksFuture<>(super.completableFuture.acceptEither(other, action));
    }

    /**
     * 组合处理，只要其中一个执行完了就会执行某个任务
     */
    @Override
    public BenchmarksFuture<Void> runAfterEither(CompletionStage<?> other, Runnable action) {
        return new BenchmarksFuture<>(super.completableFuture.runAfterEither(other, action));
    }

    /**
     * 当某个任务执行完成后执行的回调方法，会将执行结果或者执行期间抛出的异常传递给回调方法。
     * 如果是正常执行则异常为null，回调方法对应的CompletableFuture的result和该任务一致；
     * 如果该任务正常执行，则get方法返回执行结果；
     * 如果是执行异常，则get方法抛出异常。
     */
    @Override
    public BenchmarksFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action) {
        return new BenchmarksFuture<>(super.completableFuture.whenComplete(action));
    }

    /**
     * 与whenComplete类似，不同的是，如果任务执行异常允许返回一个默认值。
     */
    @Override
    public <U> BenchmarksFuture<U> handle(BiFunction<? super T, Throwable, ? extends U> fn) {
        return new BenchmarksFuture<>(super.completableFuture.handle(fn));
    }

    /**
     * 某个任务执行异常时执行的回调方法，会将抛出异常作为参数传递到回调方法中。
     * 如果该任务正常执行则exceptionally方法返回的CompletionStage的result就是该任务正常执行的结果。
     */
    @Override
    public BenchmarksFuture<T> exceptionally(Function<Throwable, ? extends T> fn) {
        return new BenchmarksFuture<>(super.completableFuture.exceptionally(fn));
    }

    /**
     * Returns this BenchmarksFuture.
     */
    @Override
    public CompletableFuture<T> toCompletableFuture() {
        return super.completableFuture;
    }

    //endregion

    //region 其它成员方法包装

    /**
     * 判断任务是否完成。
     * 三种完成情况：normally（正常执行完毕）、exceptionally（执行异常）、via cancellation（取消）
     */
    @Override
    public boolean isDone() {
        return super.completableFuture.isDone();
    }

    /**
     * 阻塞获取结果或抛出受检测异常，需要显示进行try...catch处理。
     */
    @Override
    public T get() throws InterruptedException, ExecutionException {
        return super.completableFuture.get();
    }

    /**
     * 超时阻塞获取结果
     */
    @Override
    public T get(long timeout, @NonNull TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
        return super.completableFuture.get(timeout, unit);
    }

    /**
     * 阻塞获取结果或抛出非受检异常。
     */
    public T join() {
        return super.completableFuture.join();
    }

    /**
     * 若当前任务无结果，则返回valueIfAbsent，否则返回已完成任务的结果。
     */
    public T getNow(T valueIfAbsent) {
        return super.completableFuture.getNow(valueIfAbsent);
    }

    /**
     * 取消任务，若一个任务未完成，则以CancellationException异常。
     * 其相关未完成的子任务也会以CompletionException结束。
     */
    @Override
    public boolean cancel(boolean mayInterruptIfRunning) {
        return super.completableFuture.cancel(mayInterruptIfRunning);
    }

    /**
     * 是否已取消，在任务正常执行完成前取消，才为true。否则为false。
     */
    @Override
    public boolean isCancelled() {
        return super.completableFuture.isCancelled();
    }

    /**
     * 直接赋值计算结果，内部会发送完成状态，再次调用无效。
     */
    public void obtrudeValue(T value) {
        super.completableFuture.obtrudeValue(value);
    }

    /**
     * 直接赋值计算异常，内部会发送完成状态，再次调用无效。
     */
    public void obtrudeException(Throwable ex) {
        super.completableFuture.obtrudeException(ex);
    }

    /**
     * 设置任务结果，任务正常结束，之后的任务状态为已完成。
     * 通过CAS赋值计算结果，内部会发送完成状态，再次调用无效。
     */
    public boolean complete(T value) {
        return super.completableFuture.complete(value);
    }

    /**
     * 设置任务异常结果，任务异常结束，之后的任务状态为已完成。
     * 通过CAS赋值计算异常，内部会发送完成状态，再次调用无效。
     */
    public boolean completeExceptionally(Throwable ex) {
        return super.completableFuture.completeExceptionally(ex);
    }

    /**
     * 判断任务是否异常结束，用于确定CompletableFuture是否以任何特殊方式完成。
     * 异常可能的原因有：取消、显示设置任务异常结果、任务动作执行异常等。
     */
    public boolean isCompletedExceptionally() {
        return super.completableFuture.isCompletedExceptionally();
    }

    /**
     * 返回依赖当前任务的任务数量，主要用于监控。
     */
    public int getNumberOfDependents() {
        return super.completableFuture.getNumberOfDependents();
    }

    /**
     * Returns a string identifying this CompletableFuture, as well as its state.
     */
    @Override
    public String toString() {
        return super.completableFuture.toString();
    }

    //endregion

}
